<?php
defined('ROOT_PATH') or exit;

class cms_content extends model {
    private $data = array();		// 防止重复查询

    public $flag_arr = array(
        1=>'推荐',2=>'热点',3=>'头条',4=>'精选',5=>'幻灯'
    );

	function __construct() {
		$this->table = '';			// 表名 (可以是 cms_article、cms_product、cms_photo 等)
		$this->pri = array('id');	// 主键
		$this->maxid = 'id';		// 自增字段

        if( $_ENV['_config']['admin_lang'] != 'zh-cn' ){
            $this->flag_arr = array(1=>lang('flag_1'),2=>lang('flag_2'),3=>lang('flag_3'),4=>lang('flag_4'),5=>lang('flag_5'));
        }
	}

	// 暂时用些方法解决获取 cfg 值
	function __get($var) {
		if($var == 'cfg') {
			return $this->cfg = $this->runtime->xget();
		}else{
			return parent::__get($var);
		}
	}

	//属性多选框 $val值以英文逗号隔开
	public function flag_html($val = '', $split = '', $other = ''){
	    return form::layui_loop('checkbox', 'flag', $this->flag_arr, $val, $split, $other);
    }

	// 格式化内容数组
	public function format(&$v, $mid, $dateformat = 'Y-m-d H:i', $titlenum = 0, $intronum = 0, $field_format = 0) {
		// hook cms_content_model_format_before.php

		if(empty($v)) return FALSE;

        if($dateformat == 'human_date'){
            $v['date'] = human_date($v['dateline']);
        }else{
            $v['date'] = date($dateformat, $v['dateline']);
        }
		$v['subject'] = $titlenum ? utf8::cutstr_cn($v['title'], $titlenum) : $v['title'];

        $v['url'] = $this->content_url($v['cid'], $v['id'], $v['alias'], $mid);
        $v['absolute_url'] = http().$this->cfg['webdomain'].$v['url'];	//绝对URL地址（完整）

		$v['tags'] = _json_decode($v['tags']);
		if($v['tags']) {
			$v['tag_arr'] = array();
			foreach($v['tags'] as $tagid=>$name) {
				$v['tag_arr'][] = array('name'=>$name, 'url'=> $this->tag_url($mid, $name, $tagid), 'tagid'=>$tagid);
			}
		}

		$intronum && $v['intro'] = utf8::cutstr_cn($v['intro'], $intronum);
        //缩略图
        if( empty($v['pic']) ){
            $v['haspic'] = 0;
            $v['pic'] = $v['pic_thumb'] = $this->cfg['webdir'].'static/img/nopic.gif';
        }else{
            $v['haspic'] = 1;
            if( substr($v['pic'], 0, 2) != '//' && substr($v['pic'], 0, 4) != 'http' ){ //不是外链图片
				//解决pic字段 存放是 / 开头的？
				if(substr($v['pic'], 0 , 1) == '/'){
					$v['pic'] = substr($v['pic'], 1);
				}
                $v['pic_thumb'] = $this->cfg['webdir'].image::thumb_name($v['pic']);
                $v['pic'] = $this->cfg['webdir'].$v['pic'];
            }else{
                $v['pic_thumb'] = $v['pic'];
            }
        }
        //跳转URL
        if($v['jumpurl']){
            $v['url'] = $v['jumpurl'];
        }
        //用户主页URL和用户头像
        if($v['uid']){
            $v['user_url'] = $this->space_url($v['uid']);
            $v['avatar'] = $this->user_avatar($v['uid']);
        }

        //格式化主表扩展字段的值
        if($field_format && plugin_is_enable('models_filed')){
            if(isset($this->data['models_field'.$mid]) && !empty($this->data['models_field'.$mid])) {
                $models_field = $this->data['models_field'.$mid];
            }else{
                $models_field = $this->models_field->user_defined_field($mid);
                $this->data['models_field'.$mid] = $models_field;
            }
            $this->models_field->field_val_format($models_field, $v);
        }

		// hook cms_content_model_format_after.php
	}

	// 获取内容列表
	public function list_arr($where, $orderby, $orderway, $start, $limit, $total) {
		// 优化大数据量翻页
		if($start > 1000 && $total > 2000 && $start > $total/2) {
			$orderway = -$orderway;
			$newstart = $total-$start-$limit;
			if($newstart < 0) {
				$limit += $newstart;
				$newstart = 0;
			}
			$list_arr = $this->find_fetch($where, array($orderby => $orderway), $newstart, $limit);
			return array_reverse($list_arr, TRUE);
		}else{
			return $this->find_fetch($where, array($orderby => $orderway), $start, $limit);
		}
	}

    //发布或编辑内容时检查数据
    public function check_post($post = array(), $isadd = 1){
        // hook cms_content_model_check_post_before.php
        if( empty($post['cid']) ){
            return lang('please_select_category');
        }elseif ( empty($post['title']) ){
            return lang('please_fill_title');
        }elseif ( isset($post['content']) && strlen($post['content']) < 5 ){
            return lang('please_fill_content_over_5');
        }elseif ( $isadd && isset($post['alias'] ) && $post['alias'] && $err_msg = $this->only_alias->check_alias($post['alias'], 1) ){
            return $err_msg;
        }elseif ( isset($post['id']) && empty($post['id']) ){
            return lang('id_not_exists');
        }
        // hook cms_content_model_check_post_after.php
        return '';
    }

	//发布内容
    public function xadd($post = array(), $user = array(), $table = 'article'){
        // hook cms_content_model_xadd_before.php

        //火车头数据过滤
        if(isset($post['alias']) && $post['alias'] == '[db:别名]') $post['alias'] = '';
        if(isset($post['tags']) && $post['tags'] == '[db:标签]' ) $post['tags'] = '';
        if(isset($post['pic']) && $post['pic'] == '[db:缩略图]' ) $post['pic'] = '';
        if(isset($post['flag']) && $post['flag'] == '[db:属性]' ) $post['flag'] = array();
        if(isset($post['intro']) && $post['intro'] == '[db:摘要]' ) $post['intro'] = '';
        if(isset($post['author']) && $post['author'] == '[db:作者]' ) $post['author'] = '';
        if(isset($post['source']) && $post['source'] == '[db:来源]' ) $post['source'] = '';
        if(isset($post['views']) && $post['views'] == '[db:浏览量]' ) $post['views'] = 0;
        if(isset($post['seo_title']) && $post['seo_title'] == '[db:SEO标题]' ) $post['seo_title'] = '';
        if(isset($post['seo_keywords']) && $post['seo_keywords'] == '[db:SEO关键词]' ) $post['seo_keywords'] = '';
        if(isset($post['seo_description']) && $post['seo_description'] == '[db:SEO描述]' ) $post['seo_description'] = '';
        if(isset($post['jumpurl']) && $post['jumpurl'] == '[db:跳转URL]' ) $post['jumpurl'] = '';
        if(isset($post['isremote']) && $post['isremote'] == '[db:远程图片本地化]' ) $post['isremote'] = 0;
        if(isset($post['iscomment']) && $post['iscomment'] == '[db:禁止评论]' ) $post['iscomment'] = 0;
        //end

        unset($post['id']);
        $err = $this->check_post($post);
        if($err){
            return array('err'=>1 ,'msg'=>$err);
        }
        $isremote = isset($post['isremote']) ? (int)$post['isremote'] : 0;
        $cid = isset($post['cid']) ? (int)$post['cid'] : 0;
        $uid = isset($user['uid']) ? (int)$user['uid'] : (isset($post['uid']) ? (int)$post['uid'] : 1);
        if( empty($user) ){
            $user = $this->user->get($uid);
            if( empty($user) ){
                return array('err'=>1 ,'msg'=>lang('user_not_exists'));
            }
        }
        $title = isset($post['title']) ? trim(strip_tags($post['title'])) : '';
        $contentstr = isset($post['content']) ? trim($post['content']) : '';
        // 如果摘要为空，自动生成摘要
        $intro = isset($post['intro']) ? trim($post['intro']) : '';
        $intro = auto_intro($intro, $contentstr);

        $tagstr = isset($post['tags']) ? trim($post['tags'], ", \t\n\r\0\x0B") : '';
        $flags = isset($post['flag']) ? (is_array($post['flag']) ? $post['flag'] : explode(',',$post['flag'])) : array();
        $author =isset($post['author']) ? trim($post['author']) : '';
        if( empty($author) ){
            $author = empty($user['author'] ) ? $user['username'] : $user['author'];
        }
        $alias = isset($post['alias']) ? strtolower(trim($post['alias'])) : '';
        if($alias && preg_match("/^\d+_\d+$/u",$alias)){    // 数字_数字 会和没有别名的 别名型URL冲突，导致404页面
            return array('err'=>1 ,'msg'=>lang('alias_error_number_and_number'));
        }
        // hook cms_content_model_xadd_info_after.php

        //分类检查
        $categorys = $this->category->read($cid);
        if(empty($categorys)){
            return array('err'=>1 ,'msg'=>lang('category_not_exists'));
        }
        $mid = (int)$categorys['mid'];
        $models = $this->models->get($mid);
        if(empty($models) || $models['tablename'] != $table){
            return array('err'=>1 ,'msg'=>lang('cid_error'));
        }

        // hook cms_content_model_xadd_category_after.php

        $cms_content = array(
            'cid' => $cid,
            'title' => $title,
            'alias' => $alias,
            'tags' => '',
            'intro' => $intro,
            'pic' => isset($post['pic']) ? trim($post['pic']) : '',
            'uid' => $uid,
            'author' => $author,
            'source' => isset($post['source']) ? trim($post['source']) : '',
            'dateline' => isset($post['dateline']) ? $post['dateline'] : $_ENV['_time'],
            'lasttime' => isset($post['lasttime']) ? $post['lasttime'] : $_ENV['_time'],
            'ip' => isset($post['ip']) ? $post['ip'] : ip2long($_ENV['_ip']),
            'iscomment' => isset($post['iscomment']) ? (int)$post['iscomment'] : 0,
            'flags' => implode(',', $flags),
            'seo_title' => isset($post['seo_title']) ? trim(strip_tags($post['seo_title'])) : '',
            'seo_keywords' => isset($post['seo_keywords']) ? trim(strip_tags($post['seo_keywords'])) : '',
            'seo_description' => isset($post['seo_description']) ? trim(strip_tags($post['seo_description'])) : '',
            'jumpurl' => isset($post['jumpurl']) ? trim($post['jumpurl']) : '',
        );
        // hook cms_content_model_xadd_cms_content_after.php

        $cms_content_data = array(
            'content'=>$contentstr,
        );

        // hook cms_content_model_xadd_cms_content_data_after.php

        $endstr = '';
        $this->cms_content_attach->table = 'cms_'.$table.'_attach';
        if($isremote) {
            $endstr .= $this->get_remote_img($table, $cms_content_data['content'], $uid, $cid);
        }

        // 计算图片数，和非图片文件数
        $imagenum = $this->cms_content_attach->find_count(array('id'=>0, 'uid'=>$uid, 'isimage'=>1));
        $filenum = $this->cms_content_attach->find_count(array('id'=>0, 'uid'=>$uid, 'isimage'=>0));
        if($imagenum || $filenum){
            $cms_content['imagenum'] = $imagenum;
            $cms_content['filenum'] = $filenum;
        }
        // 如果缩略图为空，并且附件表有图片，则将第一张图片设置为缩略图
        if(empty($cms_content['pic']) && $imagenum) {
            $cms_content['pic'] = $this->auto_pic($table, $uid, 0, $models);
        }

        //匹配内容里面的图片（这里不生成缩略图小图，直接是完整的图片网址）
        if(empty($cms_content['pic'])){
            $pattern="/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
            preg_match_all($pattern, $contentstr, $match);
            if( isset($match[1]) ){
                $cms_content['pic'] = isset($match[1][0]) ? $match[1][0] : '';
            }
        }
        //处理缩略图 end

        //标签处理 start
        $tagdatas = $tags = array();
        if($tagstr){
            $tags_arr = explode(',', $tagstr);
            $this->cms_content_tag->table = 'cms_'.$table.'_tag';
            for($i = 0; isset($tags_arr[$i]) && $i < 8; $i++) { //只保留8个标签
                $name = safe_str($tags_arr[$i]);
                if($name && _strlen($name)<=80){  //数据表name字段长度限制80个字符
                    $tagdata = $this->cms_content_tag->find_fetch(array('name'=>$name), array(), 0, 1); //看看是否已经存在
                    if($tagdata) {
                        $tagdata = current($tagdata);
                    }else{
                        $tag_post = array('name'=>$name);
                        // hook cms_content_model_xadd_tag_post_after.php
                        $tagid = $this->cms_content_tag->create($tag_post);
                        if(!$tagid){
                            return array('err'=>1 ,'msg'=>lang('write_tag_table_failed'));
                        }
                        $tagdata = $this->cms_content_tag->get($tagid);
                    }
                    $tagdata['count']++;
                    $tagdatas[] = $tagdata;
					if( _strlen(_json_encode($tags)) > 500){    //主表tags长度限制
                        break;
                    }
                    $tags[$tagdata['tagid']] = $tagdata['name'];
                }
            }
        }
        if($tags){
            $cms_content['tags'] = _json_encode($tags);
        }
        //标签处理 end

        //写入主表
        $this->table = 'cms_'.$table;
        $id = $this->create($cms_content);
        if($id) {
            // hook cms_content_model_xadd_cms_content_success.php
        }else{
            return array('err'=>1 ,'msg'=>lang('write_content_table_failed'));
        }

        //附表数据
        $this->cms_content_data->table = 'cms_'.$table.'_data';
        if($this->cms_content_data->set($id, $cms_content_data)) {
            // hook cms_content_model_xadd_cms_content_data_success.php
        }else{
            $this->delete($id);    //删除主表数据
            return array('err'=>1 ,'msg'=>lang('write_content_data_table_failed'));
        }

        // 写入内容查看数表
        $this->cms_content_views->table = 'cms_'.$table.'_views';
        $cms_content_views = array(
            'cid'=>$cid,
            'views'=>isset($post['views']) ? (int)$post['views'] : 0,
        );
        // hook cms_content_model_xadd_cms_content_views_after.php

        if(!$this->cms_content_views->set($id, $cms_content_views)) {
            $this->delete($id);    //删除主表数据
            $this->cms_content_data->delete($id);   //删除附表数据
            return array('err'=>1 ,'msg'=>lang('write_content_views_table_failed'));
        }

        // 写入全站唯一别名表
        if($alias && !$this->only_alias->create(array('alias'=> $alias ,'mid' => $mid, 'cid' => $cid, 'id' => $id))) {
            $this->update(array('id'=>$id, 'alias'=>''));
        }

        //标签表和标签内容表对应
        if($tagdatas){
            $this->cms_content_tag_data->table = 'cms_'.$table.'_tag_data';
            foreach($tagdatas as $tagdata) {
                $this->cms_content_tag->update($tagdata);
                $this->cms_content_tag_data->set(array($tagdata['tagid'], $id), array('id'=>$id));
            }
        }

        // 写入内容属性标记表
        if($flags){
            $this->cms_content_flag->table = 'cms_'.$table.'_flag';
            foreach($flags as $flag) {
                $this->cms_content_flag->set(array($flag, $id), array('cid'=>$cid));
            }
        }

        // 更新附件归宿 cid 和 id
        if($imagenum || $filenum) {
            $this->cms_content_attach->find_update(array('id'=>0, 'uid'=>$uid), array('cid'=>$cid, 'id'=>$id));
        }

        // 更新用户发布的内容条数
        $user['contents']++;
        $this->user->update($user);

        // 更新分类的内容条数
        $categorys['count']++;
        $this->category->update($categorys);
        $this->category->update_cache($cid);

        //返回数据
        $return_data = array(
            'cid'=>$cid,
            'id'=>$id,
            'alias'=>$alias,
            'mid'=>$mid
        );

        // hook cms_content_model_xadd_after.php

        return array('err'=>0, 'msg'=>lang('fabu_sucessfully').$endstr, 'data'=>$return_data);
    }

    //编辑内容
    public function xedit($post = array(), $user = array(), $table = 'article'){
        // hook cms_content_model_xedit_before.php
        if( !isset($post['id']) ){
            return array('err'=>1 ,'msg'=>lang('id_not_exists'));
        }
        $isremote = isset($post['isremote']) ? (int)$post['isremote'] : 0;

        $err = $this->check_post($post, 0);
        if($err){
            return array('err'=>1 ,'msg'=>$err);
        }

        $this->table = 'cms_'.$table;
        $id = (int)$post['id'];
        $olddata = $this->cms_content->get($id);
        if(empty($olddata)){
            return array('err'=>1 ,'msg'=>lang('data_no_exists'));
        }

        $cid = isset($post['cid']) ? (int)$post['cid'] : 0;
        $uid = isset($user['uid']) ? (int)$user['uid'] : 1;
        $title = isset($post['title']) ? trim(strip_tags($post['title'])) : '';
        $contentstr = isset($post['content']) ? trim($post['content']) : '';
        // 如果摘要为空，自动生成摘要
        $intro = isset($post['intro']) ? trim($post['intro']) : '';
        $intro = auto_intro($intro, $contentstr);

        $tagstr = isset($post['tags']) ? trim($post['tags'], ", \t\n\r\0\x0B") : '';
        $flags = isset($post['flag']) ? (array)$post['flag'] : array();
        $author =isset($post['author']) ? trim($post['author']) : '';
        if( empty($author) ){
            $author = empty($user['author'] ) ? $user['username'] : $user['author'];
        }
        $alias = isset($post['alias']) ? strtolower(trim($post['alias'])) : '';
        if($alias && preg_match("/^\d+_\d+$/u",$alias)){    // 数字_数字 会和没有别名的 别名型URL冲突，导致404页面
            return array('err'=>1 ,'msg'=>lang('alias_error_number_and_number'));
        }
        // hook cms_content_model_xedit_info_after.php

        //分类检查
        $categorys = $this->category->read($cid);
        if(empty($categorys)){
            return array('err'=>1 ,'msg'=>lang('category_not_exists'));
        }
        $mid = (int)$categorys['mid'];
        $models = $this->models->get($mid);
        if(empty($models) || $models['tablename'] != $table){
            return array('err'=>1 ,'msg'=>lang('cid_error'));
        }

        // hook cms_content_model_xedit_category_after.php

        // 检测别名是否能用
        $alias_old = $olddata['alias'];
        if($alias && $alias != $alias_old && $err_msg = $this->only_alias->check_alias($alias, 1)) {
            return array('err'=>1 ,'msg'=>$err_msg);
        }

        $cms_content = array(
            'id' => $id,
            'cid' => $cid,
            'title' => $title,
            'alias' => $alias,
            'tags' => '',
            'intro' => $intro,
            'pic' => isset($post['pic']) ? trim($post['pic']) : '',
            'uid' => $uid,
            'author' => $author,
            'source' => isset($post['source']) ? trim($post['source']) : '',
            'lasttime' => isset($post['lasttime']) ? $post['lasttime'] : $_ENV['_time'],
            'ip' => isset($post['ip']) ? $post['ip'] : ip2long($_ENV['_ip']),
            'iscomment' => isset($post['iscomment']) ? (int)$post['iscomment'] : 0,
            'flags' => implode(',', $flags),
            'seo_title' => isset($post['seo_title']) ? trim(strip_tags($post['seo_title'])) : '',
            'seo_keywords' => isset($post['seo_keywords']) ? trim(strip_tags($post['seo_keywords'])) : '',
            'seo_description' => isset($post['seo_description']) ? trim(strip_tags($post['seo_description'])) : '',
            'jumpurl' => isset($post['jumpurl']) ? trim($post['jumpurl']) : '',
        );
        // hook cms_content_model_xedit_cms_content_after.php

        $cms_content_data = array(
            'content'=>$contentstr,
        );
        // hook cms_content_model_xedit_cms_content_data_after.php

        $endstr = '';
        $this->cms_content_attach->table = 'cms_'.$table.'_attach';
        if($isremote) {
            $endstr .= $this->get_remote_img($table, $cms_content_data['content'], $uid, $cid, $id);
        }

        // 计算图片数，和非图片文件数
        $imagenum = $this->cms_content_attach->find_count(array('id'=>$id, 'uid'=>$uid, 'isimage'=>1));
        $filenum = $this->cms_content_attach->find_count(array('id'=>$id, 'uid'=>$uid, 'isimage'=>0));
        if($imagenum || $filenum){
            $cms_content['imagenum'] = $imagenum;
            $cms_content['filenum'] = $filenum;
        }

        // 如果缩略图为空，并且附件表有图片，则将第一张图片设置为缩略图
        if(empty($cms_content['pic']) && $imagenum) {
            $cms_content['pic'] = $this->auto_pic($table, $uid, $id, $models);
        }

        //匹配内容里面的图片（这里不生成缩略图小图，直接是完整的图片网址）
        if(empty($cms_content['pic'])){
            $pattern="/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
            preg_match_all($pattern, $contentstr, $match);
            if( isset($match[1]) ){
                $cms_content['pic'] = isset($match[1][0]) ? $match[1][0] : '';
            }
        }
        //处理缩略图 end

        // 比较属性变化
        $flags_old = array();
        if($olddata['flags']) {
            $flags_old = explode(',', $olddata['flags']);
            foreach($flags as $flag) {
                $key = array_search($flag, $flags_old);
                if($key !== false) unset($flags_old[$key]);
            }
        }

        // 比较标签变化
        $tags_new = explode(',', $tagstr);
        $tags_old = (array)_json_decode($olddata['tags']);
        $tags_arr = $tags = array();
        foreach($tags_new as $tagname) {
            $key = array_search($tagname, $tags_old);
            if($key === false) {
                $tags_arr[] = $tagname;
            }else{
                $tags[$key] = $tagname;
                unset($tags_old[$key]);
            }
        }

        // 标签预处理，最多支持8个标签
        $this->cms_content_tag->table = 'cms_'.$table.'_tag';
        $tagdatas = array();
        for($i = 0; isset($tags_arr[$i]) && $i < 8; $i++) {
            $name = safe_str($tags_arr[$i]);
            if($name && mb_strlen($name)<=80) {
                $tagdata = $this->cms_content_tag->find_fetch(array('name'=>$name), array(), 0, 1);
                if($tagdata) {
                    $tagdata = current($tagdata);
                }else{
                    $tagid = $this->cms_content_tag->create(array('name'=>$name, 'count'=>0, 'content'=>''));
                    if(!$tagid){
                        return array('err'=>1 ,'msg'=>lang('write_tag_table_failed'));
                    }
                    $tagdata = $this->cms_content_tag->get($tagid);
                }
                $tagdata['count']++;
                $tagdatas[] = $tagdata;
				if( _strlen(_json_encode($tags)) > 500){    //主表tags长度限制
                    break;
                }
                $tags[$tagdata['tagid']] = $tagdata['name'];
            }
        }
        if($tags){
            $cms_content['tags'] = _json_encode($tags);
        }
        //标签处理 end

        if($this->cms_content->update($cms_content)) {
            // hook cms_content_model_xedit_cms_content_success.php

            // 编辑时，别名有三种情况需要处理
            if($alias && $alias_old && $alias != $alias_old) {
                // 写入新别名
                if(!$this->only_alias->set($alias, array('mid' => $mid, 'cid' => $cid, 'id' => $id))) {
                    $this->update(array('id'=>$id, 'alias'=>''));
                }

                // 删除旧别名
                $this->only_alias->delete($alias_old);
            }elseif($alias && empty($alias_old)) {
                // 写入新别名
                if(!$this->only_alias->set($alias, array('mid' => $mid, 'cid' => $cid, 'id' => $id))) {
                    $this->update(array('id'=>$id, 'alias'=>''));
                }
            }elseif(empty($alias) && $alias_old) {
                // 删除旧别名
                $this->only_alias->delete($alias_old);
            }

        }else{
            return array('err'=>1 ,'msg'=>lang('write_content_table_failed'));
        }

        //附表数据
        $this->cms_content_data->table = 'cms_'.$table.'_data';
        if($this->cms_content_data->set($id, $cms_content_data)) {
            // hook cms_content_model_xedit_cms_content_data_success.php
        }else{
            return array('err'=>1 ,'msg'=>lang('write_content_data_table_failed'));
        }

        // 写入内容查看数表
        $this->cms_content_views->table = 'cms_'.$table.'_views';
        $cms_content_views = array(
            'cid'=>$cid,
            'views'=>isset($post['views']) ? (int)$post['views'] : 0,
        );
        // hook cms_content_model_xedit_cms_content_views_after.php

        if($this->cms_content_views->set($id, $cms_content_views)) {
            // hook cms_content_model_xedit_cms_content_views_success.php
        }else{
            return array('err'=>1 ,'msg'=>lang('write_content_views_table_failed'));
        }

        // 写入内容属性标记表
        $this->cms_content_flag->table = 'cms_'.$table.'_flag';
        foreach($flags as $flag) {
            $this->cms_content_flag->set(array($flag, $id), array('cid'=>$cid));
        }
        // 删除去掉的属性
        foreach($flags_old as $flag) {
            $flag = intval($flag);
            if($flag) $this->cms_content_flag->delete($flag, $id);
        }

        // 写入内容标签表
        $this->cms_content_tag_data->table = 'cms_'.$table.'_tag_data';
        foreach($tagdatas as $tagdata) {
            $this->cms_content_tag->update($tagdata);
            $this->cms_content_tag_data->set(array($tagdata['tagid'], $id), array('id'=>$id));
        }
        // 删除不用的标签
        foreach($tags_old as $tagid => $tagname) {
            $tagdata = $this->cms_content_tag->get($tagid);
            $tagdata['count']--;
            $this->cms_content_tag->update($tagdata);
            $this->cms_content_tag_data->delete($tagid, $id);
        }

        //改变分类了
        if($cid != $olddata['cid']){
            // 旧的分类内容数减1
            $categorys_old = $this->category->read($olddata['cid']);
            $categorys_old['count'] = max(0, $categorys_old['count']-1);
            $this->category->update($categorys_old);

            // 新的分类内容数加1
            $categorys['count']++;
            $this->category->update($categorys);

            $this->category->delete_cache();

            if($alias_old == $alias){   //这里只处理别名未变动情况下的cid更新，别名有变动的话 会在上面的三种情况下更新数据
                if(!$this->only_alias->set($alias, array('mid' => $mid, 'cid' => $cid, 'id' => $id))) {
                    $this->update(array('id'=>$id, 'alias'=>''));
                }
            }

            //更新附件表的cid
            $this->cms_content_attach->find_update(array('id'=>$id), array('cid'=>$cid));

            //更新评论排序表的cid
            if($olddata['comments']){
                $this->cms_content_comment_sort->find_update(array('mid'=>$mid, 'id'=>$id), array('cid'=>$cid));
            }

            // hook cms_content_model_xedit_cid_change_after.php
        }

	//返回数据
        $return_data = array(
            'cid'=>$cid,
            'id'=>$id,
            'alias'=>$alias,
            'mid'=>$mid
        );
        // hook cms_content_model_xedit_after.php

        return array('err'=>0, 'msg'=>lang('edit_sucessfully').$endstr, 'data'=>$return_data);
    }

	// 内容关联删除
	public function xdelete($table, $id, $cid) {
		// hook cms_content_model_xdelete_before.php

		$this->table = 'cms_'.$table;
		$this->cms_content_data->table = 'cms_'.$table.'_data';
		$this->cms_content_attach->table = 'cms_'.$table.'_attach';
		$this->cms_content_flag->table = 'cms_'.$table.'_flag';
		$this->cms_content_tag->table = 'cms_'.$table.'_tag';
		$this->cms_content_tag_data->table = 'cms_'.$table.'_tag_data';
		$this->cms_content_views->table = 'cms_'.$table.'_views';

		// 内容读取
		$data = $this->read($id);
		if(empty($data)) return lang('data_no_exists');

		// 删除附件
		$attach_arr = $this->cms_content_attach->find_fetch(array('id'=>$id));
		$updir = ROOT_PATH.'upload/'.$table.'/';
		foreach($attach_arr as $v) {
			$file = $updir.$v['filepath'];
			$thumb = image::thumb_name($file);
			try{
				is_file($file) && unlink($file);
				is_file($thumb) && unlink($thumb);
			}catch(Exception $e) {}
			$this->cms_content_attach->delete($v['aid']);
		}

		// 更新标签表
		if(!empty($data['tags'])) {
			$tags_arr = _json_decode($data['tags']);
			foreach($tags_arr as $tagid => $name) {
				$this->cms_content_tag_data->delete($tagid, $id);
				$tagdata = $this->cms_content_tag->read($tagid);
				$tagdata['count']--;
				if($tagdata['count'] > 0) {
                    $this->cms_content_tag->update($tagdata);
                }else{
                    $this->cms_content_tag->delete($tagid);
                }
			}
		}

		// 更新分类表
		$catedata = $this->category->read($cid);
		if(empty($catedata)) return lang('category_not_exists');
		if($catedata['count'] > 0) {
			$catedata['count']--;
			if(!$this->category->update($catedata)) return lang('write_content_table_failed');
			$this->category->update_cache($cid);
		}

		//更新用户内容数
        if($data['uid']){
            $user = $this->user->get($data['uid']);
            if($user && $user['contents'] > 0) {
                $user['contents']--;
                $this->user->update($user);
            }
        }

		// 删除内容
		$this->cms_content_data->delete($id);
		$this->cms_content_views->delete($id);
		$this->cms_content_flag->find_delete(array('id'=>$id));
		!empty($data['alias']) && $this->only_alias->delete($data['alias']);

        // 删除评论
        if($data['comments']){
            $where = array('mid'=>$catedata['mid'], 'id'=>$id);
            $this->cms_content_comment->find_delete($where);
            $this->cms_content_comment_sort->find_delete($where);
        }

		$ret = $this->delete($id);

        // hook cms_content_model_xdelete_after.php
		return $ret ? '' : lang('delete_failed');
	}

	// 标签链接格式化
	public function tag_url(&$mid, &$name, &$tagid, $page = FALSE) {
		// hook cms_content_model_tag_url_before.php

        $link_tag_type = isset($this->cfg['link_tag_type']) ? (int)$this->cfg['link_tag_type'] : 0;
		if(empty($_ENV['_config']['lecms_parseurl'])) {
			$s = $page ? '-page-{page}' : '';
			switch ($link_tag_type){
                case 0:
                    return $this->cfg['webdir'].'index.php?tag-'.($mid > 2 ? '-mid-'.$mid : '').'-name-'.urlencode($name).$s.$_ENV['_config']['url_suffix'];
                    break;
                case 1:
                    return $this->cfg['webdir'].'index.php?tag-'.($mid > 2 ? '-mid-'.$mid : '').'-tagid-'.$tagid.$s.$_ENV['_config']['url_suffix'];
                    break;
                case 2:
                    $encrypt = encrypt($mid.'_'.$tagid);
                    return $this->cfg['webdir'].'index.php?tag--encrypt-'.$encrypt.$s.$_ENV['_config']['url_suffix'];
                    break;
            }
		}else{
            $s = $page ? '/{page}' : '';
            switch ($link_tag_type){
                case 0:
                    return $this->cfg['webdir'].$this->cfg['link_tag_pre'].($mid > 2 ? $mid.'_' : '').urlencode($name).$s.$this->cfg['link_tag_end'];
                    break;
                case 1:
                    return $this->cfg['webdir'].$this->cfg['link_tag_pre'].($mid > 2 ? $mid.'_' : '').$tagid.$s.$this->cfg['link_tag_end'];
                    break;
                case 2:
                    $encrypt = encrypt($mid.'_'.$tagid);
                    return $this->cfg['webdir'] . $this->cfg['link_tag_pre'] . $encrypt.$s.$this->cfg['link_tag_end'];
                    break;
            }
		}
        // hook cms_content_model_tag_url_after.php
	}

    // 全部标签URL
    public function tag_all_url(&$mid, $page = FALSE, $extra = array()) {
        // hook cms_content_model_tag_all_url_before.php

        $s = '';
        $mid > 2 && $s .= '-mid-'.$mid;
        $page && $s .= '-page-{page}';

        if(empty($_ENV['_config']['lecms_parseurl'])) {
            $url = $this->cfg['webdir'].'index.php?tag-all'.$mid.$s;
        }else{
            $url = $this->cfg['webdir'].'tag_all'.$mid.$s;
        }

        // 附加参数
        if($extra) {
            foreach ($extra as $k=>$v){
                $url .= '-'.$k.'-'.$v;
            }
        }
        return $url.$_ENV['_config']['url_suffix'];
    }

    // 属性内容链接格式化
    public function flag_url($mid = 2, $flag = 1, $page = FALSE) {
        // hook cms_content_model_flag_url_before.php

        if(empty($_ENV['_config']['lecms_parseurl'])) {
            $s = $page ? '-page-{page}' : '';
            return $this->cfg['webdir'].'index.php?flags--mid-'.$mid.'-flag-'.$flag.$s.$_ENV['_config']['url_suffix'];
        }else{
            return $this->cfg['webdir'].'flags/'.$mid.'_'.$flag.($page ? '/{page}' : '').'/';
        }
    }

	// 评论链接格式化
	public function comment_url(&$cid, &$id, $page = FALSE) {
		// hook cms_content_model_comment_url_before.php

		if(empty($_ENV['_config']['lecms_parseurl'])) {
			$s = $page ? '-page-{page}' : '';
			return $this->cfg['webdir'].'index.php?comment--cid-'.$cid.'-id-'.$id.$s.$_ENV['_config']['url_suffix'];
		}else{
			return $this->cfg['webdir'].$this->cfg['link_comment_pre'].$cid.'_'.$id.($page ? '_{page}' : '').$_ENV['_config']['url_suffix'];
		}
	}

    // 用户个人主页链接格式化
    public function space_url(&$uid, $page = FALSE) {
        // hook cms_content_model_space_url_before.php

        if(empty($_ENV['_config']['lecms_parseurl'])) {
            $s = $page ? '-page-{page}' : '';
            return $this->cfg['webdir'].'index.php?space--uid-'.$uid.$s.$_ENV['_config']['url_suffix'];
        }else{
            return $this->cfg['webdir'].$this->cfg['link_space_pre'].$uid.($page ? '/{page}' : '').$this->cfg['link_space_end'];
        }
    }

	// 首页分页链接格式化
	public function index_url(&$mid) {
		// hook cms_content_model_index_url_before.php

		if(empty($_ENV['_config']['lecms_parseurl'])) {
			return $this->cfg['webdir'].'index.php?index-index-mid-'.$mid.'-page-{page}'.$_ENV['_config']['url_suffix'];
		}else{
			return $this->cfg['webdir'].'index_'.$mid.'_{page}'.$_ENV['_config']['url_suffix'];
		}
	}

    // 搜索链接格式化
    public function search_url($mid = 2, $keyword = '', $page = FALSE) {
        // hook cms_content_model_search_url_before.php

        if(empty($_ENV['_config']['lecms_parseurl'])) {
            $s = $page ? '-page-{page}' : '';
            return $this->cfg['webdir'].'index.php?search--mid-'.$mid.'-keyword-'.urlencode($keyword).$s.$_ENV['_config']['url_suffix'];
        }else{
            $s = $page ? '/{page}' : '';
            if($mid > 2) {
                return $this->cfg['webdir'].'search/'.$mid.'_'.urlencode($keyword).$s.'/';
            }else{
                return $this->cfg['webdir'].'search/'.urlencode($keyword).$s.'/';
            }
        }
    }

    // 附件下载，用的少，不做伪静态
    public function attach_url($mid = 0, $aid = 0) {
        // hook cms_content_model_attach_url_before.php

        return $this->cfg['webdir'].'index.php?attach--mid-'.$mid.'-id-'.$aid.$_ENV['_config']['url_suffix'];
    }

	// 内容链接格式化
	public function content_url(&$cid, &$id, &$alias, &$mid) {
		// hook cms_content_model_content_url_before.php

		if(empty($_ENV['_config']['lecms_parseurl'])) {
			return $this->cfg['webdir'].'index.php?show--cid-'.$cid.'-id-'.$id.$_ENV['_config']['url_suffix'];
		}else{
			switch($this->cfg['link_show_type']) {
				case 1: //数字型
					return $this->cfg['webdir'].$cid.'/'.$id.$_ENV['_config']['url_suffix'];
				case 2: //推荐型
					return $this->cfg['webdir'].$this->cfg['cate_arr'][$cid].'/'.$id.$_ENV['_config']['url_suffix'];
				case 3: //别名型
					return $this->cfg['webdir'].($alias ? $alias : $cid.'_'.$id).$_ENV['_config']['url_suffix'];
                case 4: //加密型
                    return $this->cfg['webdir'].encrypt($cid.'_'.$id).$_ENV['_config']['url_suffix'];
                case 5: //数字型
                    if($mid > 2){
                        return $this->cfg['webdir'].$mid.'_'.$id.$_ENV['_config']['url_suffix'];
                    }else{
                        return $this->cfg['webdir'].$id.$_ENV['_config']['url_suffix'];
                    }
                case 6: //分类别名+内容别名型
                    return $this->cfg['webdir'].$this->cfg['cate_arr'][$cid].'/'.($alias ? $alias : $cid.'_'.$id).$_ENV['_config']['url_suffix'];
			}

            // hook cms_content_model_content_url_parseurl_after.php
		}
	}

    //用户模块相关URL，只涉及 user-xxx 或者 my-xxx
    public function user_url($action = 'index', $control = 'user', $page = false, $extra = array()){
        // hook cms_content_model_user_url_before.php

        $s = '';
	    if($page){
            $s .= $page ? '-page-{page}' : '';
        }
        // 附加参数
        if($extra) {
            foreach ($extra as $k=>$v){
                $s .= '-'.$k.'-'.$v;
            }
        }

        if(empty($_ENV['_config']['lecms_parseurl'])) {
            return $this->cfg['webdir'].'index.php?'.$control.'-'.$action.$s.$_ENV['_config']['url_suffix'];
        }else{
            return $this->cfg['webdir'].$control.'-'.$action.$s.$_ENV['_config']['url_suffix'];
        }
    }

	//用户头像，存储方式 upload/avatar/用户ID.png 或者 数据表avatar存储了路径
	public function user_avatar($uid = 0, $avatar_file = ''){
        // hook cms_content_model_user_avatar_before.php
        if($uid){
            if($avatar_file){
                $avatar = 'upload/avatar/'.$avatar_file;
            }else{
                $avatar = 'upload/avatar/'.$uid.'.png';
            }

            if( is_file(ROOT_PATH.$avatar) ){
                return $this->cfg['webdir'].$avatar;
            }else{
                $user = $this->user->get($uid);
                if($user['avatar'] && is_file(ROOT_PATH.$user['avatar'])){
                    return $this->cfg['webdir'].$user['avatar'];
                }
                return $this->cfg['webdir'].'static/img/avatar.png';
            }
        }else{
            return $this->cfg['webdir'].'static/img/avatar.png';
        }
    }

    // 自动生成缩略图
    public function auto_pic($table, $uid, $id = 0, $models = array()) {
        $this->cms_content_attach->table = 'cms_'.$table.'_attach';
        $pic_arr = $this->cms_content_attach->find_fetch(array('id'=>$id, 'uid'=>$uid, 'isimage'=>1), array(), 0, 1);
        if($pic_arr){
            $pic_arr = current($pic_arr);

            $path = 'upload/'.$table.'/'.$pic_arr['filepath'];
            $pic = image::thumb_name($path);
            $src_file = ROOT_PATH.$path;
            $dst_file = ROOT_PATH.$pic;
            if( !is_file($dst_file) && $models ) {
                image::thumb($src_file, $dst_file, $models['width'], $models['height'], $this->cfg['thumb_type'], $this->cfg['thumb_quality']);
                return $path;
            }else{
                return $path;
            }
        }else{
            return '';
        }
    }

    /**
     * 获取远程图片
     * @param $table 表名
     * @param $content 内容
     * @param int $uid 用户ID
     * @param int $cid 分类ID
     * @param int $id 内容ID
     * @param int $write_db 是否写入附件表
     * @return string
     */
    public function get_remote_img($table, &$content, $uid = 1, $cid = 0, $id = 0, $write_db = 1) {
        if(empty($content)){
            return '';
        }
        function_exists('set_time_limit') && set_time_limit(0);

        $updir = 'upload/'.$table.'/';
        $_ENV['_prc_err'] = 0;
        $_ENV['_prc_arg'] = array(
            'hosts'=>array('127.0.0.1', 'localhost', $_SERVER['HTTP_HOST'], $this->cfg['webdomain']),
            'uid'=>$uid,
            'cid'=>$cid,
            'id'=>$id,
            'maxSize'=>10000,
            'upDir'=>ROOT_PATH.$updir,
            'preUri'=>$this->cfg['weburl'].$updir,
            'cfg'=>$this->cfg,
            'write_db'=>$write_db
        );

        $this->cms_content_attach->table = 'cms_'.$table.'_attach';
        $content = preg_replace_callback('#\<img [^\>]*src=["\']((?:http|https|ftp)\://[^"\']+)["\'][^\>]*\>#iU', array($this, 'img_replace'), $content);
        unset($_ENV['_prc_arg']);
        return $_ENV['_prc_err'] ? lang('isremote_failed_tip_1').$_ENV['_prc_err'].lang('isremote_failed_tip_2') : '';
    }

    // 远程图片处理 (如果抓取失败则不替换)
    // $conf 用到4个参数 hosts preUri cfg upDir
    private function img_replace($mat) {
        static $uris = array();
        $uri = $mat[1];
        $conf = &$_ENV['_prc_arg'];
        if( !isset($conf['write_db']) ){
            $conf['write_db'] = 1;
        }

        // 排除重复保存相同URL图片
        if(isset($uris[$uri])) return str_replace($uri, $uris[$uri], $mat[0]);

        // 根据域名排除本站图片
        $urls = parse_url($uri);
        if(in_array($urls['host'], $conf['hosts'])) return $mat[0];

        $file = $this->cms_content_attach->remote_down($uri, $conf, (int)$conf['write_db']);
        if($file) {
            $uris[$uri] = $conf['preUri'].$file;
            $cfg = $conf['cfg'];

            // 是否添加水印
            if(!empty($cfg['watermark_pos'])) {
                image::watermark($conf['upDir'].$file, ROOT_PATH.'static/img/watermark.png', null, $cfg['watermark_pos'], $cfg['watermark_pct']);
            }
            return str_replace($uri, $uris[$uri], $mat[0]);
        }else{
            $_ENV['_prc_err']++;
            return $mat[0];
        }
    }

    // hook cms_content_model_after.php
}
